/*
 * INCLUDE FILES
 ****************************************************************************************
 */
#include "time.h"
#include "iodevice.h"

clock_param_t clock_env;

/*************day calculate**************/
#define DAYS_PER_WEEK 7
#define MONTHS 12
#define DATE_HEADER "   Sun   Mon   Tues  Wed   Thur  Fri   Sat"

//返回这一天从公元元年算起是第几天

int get_days(int year, int month, int day)
{
    int days = days_of_year(year, month, day);
    int temp = year - 1;
    return (temp * 365 + temp / 4 - temp / 100 + temp / 400 + days - 1); //dyc changed ,from 0 day begins
}

int get_sec_from_2010_1_1(uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t min, uint16_t sec)
{
    return (get_days(year, month, day) - 733772) * 86400 + hour * 3600 + min * 60 + sec;
}

//返回这一天在当年是第几天
int days_of_year(int year, int month, int day)
{
    int i;
    int days = 0;
    for (i = 1; i < month; i++)
    {
        days += days_of_month(year, i);
    }
    return days + day;
}

//返回这个月一共有多少天
int days_of_month(int year, int month)
{
    //存储平年每月的天数
    const int month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (2 == month && is_leap_year(year))
        return 29; // 如果是闰年2月，返回29天
    else
        return month_days[month - 1]; //正常返回
}

//判断是不是闰年
bool is_leap_year(int year)
{
    return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

int day_of_week(int year, int month, int day)
{
    return get_days(year, month, day) % DAYS_PER_WEEK;
}

void show_clock_func(void)
{
    Serial.printf(" time tick:%d\n", CALULATE_TIME_TICK(clock_env.hour, clock_env.min, clock_env.sec));
    Serial.printf(" %d/%d/%d %d %d:%d:%d\n", clock_env.year, clock_env.month, clock_env.day, clock_env.week, clock_env.hour, clock_env.min, clock_env.sec);
}

/*******************************************************************
* 函数名称: RTC_Clock_hdl()
* 输入参数: 无
* 返回值  : 无
* 功    能: 实时时钟硬件定时器调用，每100ms调用一次
********************************************************************/
void RTC_Clock_hdl(void)
{
    static uint32_t cur_base_time = 0;

    cur_base_time++;
    if (cur_base_time >= 10)
    {
        cur_base_time = 0;
        clock_env.sec++;
        if (clock_env.sec >= 60)
        {
            clock_env.sec = 0;
            clock_env.min++;
            show_clock_func();
            if (clock_env.min >= 60)
            {
                clock_env.min = 0;
                clock_env.hour++;
                if (clock_env.hour >= 24)
                {
                    clock_env.hour = 0;
                    clock_env.week++;

                    if (clock_env.week >= 8)
                    {
                        clock_env.week = 1;
                    }
                    clock_env.day++;

                    if (clock_env.day >= (days_of_month(clock_env.year, clock_env.month) + 1))
                    {
                        clock_env.day = 1;
                        clock_env.month++;
                        if (clock_env.month >= 13)
                        {
                            clock_env.month = 1;
                            clock_env.year++;
                        }
                    }
                }
            }
        }
    }
}

/*******************************************************************
* 函数名称: RTC_Rejuge()
* 输入参数: 无
* 返回值  : 无
* 功    能: 校准时间需要考虑是否有定时，校准的时候会不会跨过定时时间
********************************************************************/
void RTC_Rejuge(struct tm *time)
{
    clock_env.year = time->tm_year;
    clock_env.month = time->tm_mon;
    clock_env.day = time->tm_mday;
    clock_env.week = time->tm_wday;
    clock_env.min = time->tm_min;
    clock_env.hour = time->tm_hour;
    clock_env.sec = time->tm_sec;
}
